package com.ruoyi.durian.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.DurianRedisKeysType;
import com.ruoyi.common.enums.OrderType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.durian.domain.LlCardPackage;
import com.ruoyi.durian.domain.LlCoupon;
import com.ruoyi.durian.domain.LlCouponExchange;
import com.ruoyi.durian.domain.dto.CouponInfoDto;
import com.ruoyi.durian.domain.vo.CouponGrantVo;
import com.ruoyi.durian.mapper.LlCardPackageMapper;
import com.ruoyi.durian.mapper.LlCouponExchangeMapper;
import com.ruoyi.durian.service.LlCouponService;
import com.ruoyi.durian.mapper.LlCouponMapper;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author lenovo
 * @description 针对表【ll_coupon(优惠券模块-优惠券表)】的数据库操作Service实现
 * @createDate 2024-07-26 16:17:15
 */
@Service
public class LlCouponServiceImpl extends ServiceImpl<LlCouponMapper, LlCoupon>
        implements LlCouponService {

    @Resource
    private LlCouponMapper llCouponMapper;

    @Resource
    private LlCouponExchangeMapper llCouponExchangeMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private LlCardPackageMapper llCardPackageMapper;


    /**
     * 查询优惠券模块-优惠券
     *
     * @param id 优惠券模块-优惠券主键
     * @return 优惠券模块-优惠券
     */
    @Override
    public LlCoupon selectLlCouponById(Long id) {
        return llCouponMapper.selectLlCouponById(id);
    }

    /**
     * 查询优惠券模块-优惠券列表
     *
     * @param llCoupon 优惠券模块-优惠券
     * @return 优惠券模块-优惠券
     */
    @Override
    public List<LlCoupon> selectLlCouponList(LlCoupon llCoupon) {
        return llCouponMapper.selectLlCouponList(llCoupon);
    }

    /**
     * 新增优惠券模块-优惠券
     *
     * @param llCoupon 优惠券模块-优惠券
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertLlCoupon(LlCoupon llCoupon) {
        llCoupon.setCreateTime(DateUtils.getNowDate());
        llCoupon.setIsDelete(0);
        llCouponMapper.insertLlCoupon(llCoupon);
        return AjaxResult.success();
    }

    /**
     * 修改优惠券模块-优惠券
     *
     * @param llCoupon 优惠券模块-优惠券
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult updateLlCoupon(LlCoupon llCoupon) {
        llCoupon.setUpdateTime(DateUtils.getNowDate());
        return AjaxResult.success(llCouponMapper.updateLlCoupon(llCoupon));
    }

    /**
     * 批量删除优惠券模块-优惠券
     *
     * @param ids 需要删除的优惠券模块-优惠券主键
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult deleteLlCouponByIds(Long[] ids) {
        return AjaxResult.success(llCouponMapper.deleteLlCouponByIds(ids));
    }

    /**
     * 添加优惠券
     *
     * @param llCoupon
     * @return
     */
    @Override
    @Transactional
    public AjaxResult saveOrUpdateCoupon(LlCoupon llCoupon) {
        if (llCoupon == null) {
            return AjaxResult.error("优惠券信息不能为空");
        }
        String type = llCouponMapper.selectCouponType(llCoupon.getType());
        if ("折扣".equals(type)) {
            BigDecimal decimal = new BigDecimal("100");
            llCoupon.setSaleMoney(decimal.subtract(BigDecimal.valueOf(llCoupon.getSale())));
        }
        if ("满减".equals(type)) {
            llCoupon.setSaleMoney(llCoupon.getMin());
        }

        if (llCoupon.getId() == null) {
            llCoupon.setCreateTime(new Date());
        }
        llCoupon.setUpdateTime(new Date());
        llCoupon.setIsDelete(0);
        llCoupon.setStatus(0);
        saveOrUpdate(llCoupon);
        return AjaxResult.success();
    }

    /**
     * 删除优惠券
     *
     * @return
     */
    @Override
    @Transactional
    public AjaxResult delCoupon(Integer id) {
        if (id == null) {
            return AjaxResult.error("优惠券id不能为空");
        }
        LlCoupon llCoupon = llCouponMapper.selectById(id);

        if (llCoupon.getStatus() == 0) {
            return AjaxResult.error("上架的优惠券不能删除");
        }
        llCouponMapper.deleteById(id);
        return AjaxResult.success();
    }

    /**
     * 发放优惠券
     *
     * @param couponGrantVo
     * @return
     */
    @Override
    @Transactional
    public AjaxResult grantCoupon(CouponGrantVo couponGrantVo) {
        if (couponGrantVo.getCode().length() != OrderType.PAYMENT_COMPLETED.getCode()) {
            return AjaxResult.error("兑换码错误(必须是六位数!!)");
        }

        if (couponGrantVo.getNum() == null || couponGrantVo.getNum() <= 0
                || couponGrantVo.getCouponId() == null) {
            return AjaxResult.error("优惠券数量不能为空");
        }

        LlCoupon llCoupon = llCouponMapper.selectById(couponGrantVo.getCouponId());
        if (!llCoupon.getEndValidTime().after(new Date())) {
            return AjaxResult.error("优惠券过期！！！");
        }

        LambdaQueryWrapper<LlCouponExchange> qw = new LambdaQueryWrapper<>();
        qw.eq(LlCouponExchange::getCouponCode, couponGrantVo.getCode());
        LlCouponExchange checkCoupon = llCouponExchangeMapper.selectOne(qw);
        if (checkCoupon != null) {
            return AjaxResult.error("兑换码重复,请重新输入!!!");
        }

        Long userId = SecurityUtils.getUserId();
        LlCouponExchange exchange = new LlCouponExchange();
        exchange.setCouponId(couponGrantVo.getCouponId());
        exchange.setCouponCode(couponGrantVo.getCode());
        exchange.setUserId(userId);
        exchange.setRemainderNum(couponGrantVo.getNum());
        exchange.setAllNum(couponGrantVo.getNum());
        exchange.setStartTime(new Date());
        exchange.setEndTime(couponGrantVo.getEndTime());
        exchange.setCreateTime(new Date());
        exchange.setUpdateTime(new Date());
        exchange.setIsDelete(0);
        llCouponExchangeMapper.insert(exchange);

        stringRedisTemplate.opsForValue().set(DurianRedisKeysType.COUPON.getKey() + couponGrantVo.getCode()
                , couponGrantVo.getNum().toString()
                , Duration.ofMillis(
                        couponGrantVo.getEndTime().getTime() - System.currentTimeMillis()));
        return AjaxResult.success();
    }

    @Override
    public List<LlCoupon> selectList(Integer status) {
        LambdaQueryWrapper<LlCoupon> qw = new LambdaQueryWrapper<>();
        qw.eq(LlCoupon::getStatus, status).eq(LlCoupon::getIsDelete, 0);
        List<LlCoupon> llCouponList = llCouponMapper.selectList(qw);
        return llCouponList;
    }

    /**
     * 优惠券发布历史
     *
     * @return
     */
    @Override
    public List<Map<Object, String>> couponSubmitList() {
        return llCouponMapper.couponSubmitList();
    }

    /**
     * 查询我的卡券未失效的数量
     *
     * @return
     */
    @Override
    public Long couponCount() {
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<LlCardPackage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LlCardPackage::getUserId, userId)
                .eq(LlCardPackage::getIsDelete, 0)
                .eq(LlCardPackage::getStatus, 1)
                .eq(LlCardPackage::getUseStatus, 1)
                .ge(LlCardPackage::getEndTime, new Date());
        return llCardPackageMapper.selectCount(wrapper);
    }

    /**
     * 优惠券列表展示
     */
    @Override
    public AjaxResult couponSelectList() {
        LambdaQueryWrapper<LlCoupon> qw = new LambdaQueryWrapper<>();
        qw.eq(LlCoupon::getIsDelete, 0);
        List<LlCoupon> llCouponList = llCouponMapper.selectList(qw);
        return AjaxResult.success(llCouponList);
    }

    /**
     * 优惠券详情
     *
     * @param id
     * @return
     */
    @Override
    public CouponInfoDto selectByCouponId(Integer id) {
        return llCouponMapper.selectByCouponId(id);
    }
}




